package cn.maihe.elg.operation.centers.guogu.handler;

import cn.maihe.elg.operation.centers.guogu.auth.GuoGuCenterAuthConfig;
import cn.maihe.elg.operation.centers.guogu.dto.GuoGuBaseRespDTO;
import cn.maihe.elg.operation.centers.supports.annotation.CenterTradeService;
import cn.maihe.elg.operation.model.enums.CenterNoEnum;
import cn.maihe.elg.operation.model.enums.CenterProviderEnum;
import cn.maihe.elg.operation.utils.IdGenerate;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.context.annotation.Profile;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Description 测试国国中心服务的处理器类，用于模拟请求并转发至实际的国国中心处理逻辑。
 * @Author SSX
 * @Date 2025/04/24
 */
@RestController
@RequestMapping(value = "/test/center")
@Slf4j
@Profile({"dev", "test"})
public class TestGuoGuCenterHandler {
    @Resource
    private GuoGuCenterHandler guoGuCenterHandler;

    /**
     * 中心服务商
     */
    public static final CenterProviderEnum centerProvider = CenterProviderEnum.GUOGU;
    /**
     * 能够使用与该中心服务商的 中心信息
     */
    public static final List<String> enableCenterNos = Lists.newArrayList(CenterNoEnum.GUOGU.getCenterNo());
    /**
     * 中心服务商的接口实现类映射表，key为"中心编号+交易类型小写"，value为对应的交易服务实现类
     */
    private final Map<String, GuoGuCenterTradeService> tradeServiceMap = new HashMap<>();

    /**
     * 构造函数，初始化交易服务映射表。
     *
     * @param baseCenterServices 所有GuoGuCenterTradeService的实现类集合
     */
    public TestGuoGuCenterHandler(@SuppressWarnings("rawtypes") final Collection<GuoGuCenterTradeService> baseCenterServices) {
        super();
        baseCenterServices.forEach(item -> {
            CenterTradeService ts = AnnotationUtils.findAnnotation(item.getClass(), CenterTradeService.class);
            if (GuoGuCenterHandler.centerProvider == ts.provider() && enableCenterNos.contains(ts.centerNo().getCenterNo())) {
                tradeServiceMap.put(ts.centerNo().getCenterNo() + ts.tradeType().name().toLowerCase(), item);
            }
        });
    }

    /**
     * 接收测试请求，并将其转发到 doServiceTest 方法进行处理。
     *
     * @param centerNo           中心编号
     * @param orgCode            组织编码
     * @param clientId           客户端ID
     * @param headerMap          请求头参数
     * @param clearBizReqJsonBody 明文业务请求体
     * @param req                HttpServletRequest对象
     * @param resp               HttpServletResponse对象
     * @return DeferredResult<Object> 异步处理结果
     */
    @PostMapping(value = "/guogu/{centerNo}/{orgCode}/{clientId}", consumes = {"application/json", "application/xml","text/plain"})
    public @ResponseBody
    DeferredResult<Object> serviceTest(@PathVariable("centerNo") String centerNo, @PathVariable("orgCode") String orgCode, @PathVariable("clientId") String clientId, @RequestHeader(required = false) Map<String, Object> headerMap, @RequestBody final String clearBizReqJsonBody, final HttpServletRequest req, final HttpServletResponse resp) {
        return this.doServiceTest(centerNo, orgCode,(String) headerMap.get("method"), clientId, req, resp,  clearBizReqJsonBody, null);
    }

    /**
     * 实际执行测试请求处理的方法。
     *
     * @param centerNo           中心编号
     * @param orgCode            组织编码
     * @param tradeType          交易类型（从请求头中获取）
     * @param clientId           客户端ID
     * @param req                HttpServletRequest对象
     * @param resp               HttpServletResponse对象
     * @param clearBizReqJsonBody 明文业务请求体
     * @param multipartFileMap   文件上传参数（当前未使用）
     * @return DeferredResult<Object> 处理结果
     */
    protected DeferredResult<Object> doServiceTest(String centerNo, String orgCode, String tradeType, String clientId,final HttpServletRequest req, final HttpServletResponse resp, final String clearBizReqJsonBody, final Map<String, MultipartFile> multipartFileMap) {
        DeferredResult<Object> dr = new DeferredResult<Object>();

        // 检查是否支持该交易类型
        if (!this.tradeServiceMap.containsKey(centerNo + tradeType.toLowerCase())) {
            dr.setResult(GuoGuBaseRespDTO.error("不支持的交易类型"));
            return dr;
        }

        CenterNoEnum centerNoEnum;
        try {
            centerNoEnum = CenterNoEnum.resolve(centerNo);
        } catch (Exception e) {
            log.error("暂不支持的交易中心[{}]:{}", centerNo, e.getMessage(), e);
            dr.setResult(GuoGuBaseRespDTO.error( "暂不支持的交易中心[" + centerNo + "]"));
            return dr;
        }

        // 获取认证配置
        GuoGuCenterAuthConfig authConfig = this.tradeServiceMap.get(centerNo + tradeType.toLowerCase()).getAuthConfig(centerNoEnum);

        // 加密业务数据
        String encryptAndB64ReqBody = authConfig.getGuoGuEncryption().encrypt(clearBizReqJsonBody);

        // 构造模拟请求头
        Map<String, Object> mockHeadMap = new HashMap<>();
        mockHeadMap.put("Authorization", "Bearer "+Base64.encodeBase64String((clientId+":"+ IdGenerate.get32UUID()).getBytes(StandardCharsets.UTF_8)));
        mockHeadMap.put("method",tradeType);
        mockHeadMap.put("signature",authConfig.getGuoGuAuthorization().signature(clientId,clearBizReqJsonBody));

        // 调用真实处理逻辑
        return guoGuCenterHandler.doService(centerNo, orgCode, tradeType, req, resp, mockHeadMap, encryptAndB64ReqBody);
    }
}
